package com.qf.mybatisplus.utils;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

/**
 * @ClassName: DesUtil
 * @Author:Cola.Niu
 * @date:2020/4/21 18:47
 * @Version:v1.0
 * @description: DES加解密工具类--请定期更换私钥与公钥
 */

public class DesUtil {
    public static final String PUBLIC_KEY = "KJSDfjdf==";
    public static final String PRIVATE_KEY = "KJSDfjdf==";

    public static String encrypt(String data)  {
        try {
            return encrypt(data,DesUtil.PUBLIC_KEY,"utf-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String decrypt(String data){
        try {
            return decrypt(data, DesUtil.PRIVATE_KEY,"utf-8");
        } catch (Exception e) {
            //e.printStackTrace();
            return null;
        }
    }

    /**
     * 用公钥将字符串加密
     * @param data
     * @param publicKey
     * @return
     */
    public static String encrypt(String data, String publicKey, String charsetName)throws Exception{
        if (data==null||data.trim().length()==0){
            throw new RuntimeException("加密数据为空");
        }else {
            //获得字节数组
           byte[] dataBt = data.getBytes(charsetName);
           byte[] keyBt = publicKey.getBytes(charsetName);

           // 生成一个可信任的随机数源
            SecureRandom sr = new SecureRandom();

            // 从原始密钥数据创建DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(keyBt);

            // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(dks);

            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");

            // 用密钥初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

            byte[] enDataBy =  cipher.doFinal(dataBt);

            return new BASE64Encoder().encode(cipher.doFinal(dataBt));
        }

    }

    /**
     * 用公钥将字符串加密
     * @param data
     * @param privateKey
     * @return
     */
    public static String decrypt(String data,String privateKey,String charsetName)throws Exception{
        if (data==null||data.trim().length()==0){
            throw new RuntimeException("加密数据为空");
        }else {
            BASE64Decoder decoder = new BASE64Decoder();
            //获得字节数组
            byte[] dataBt = decoder.decodeBuffer(data);
            byte[] keyBt = privateKey.getBytes(charsetName);

            // 生成一个可信任的随机数源
            SecureRandom sr = new SecureRandom();

            // 从原始密钥数据创建DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(keyBt);

            // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(dks);

            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");

            // 用密钥初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

            byte[] deDataBt =  cipher.doFinal(dataBt);

            return new String(deDataBt,charsetName);
        }
    }
    /**
     * AES加密字符串

     */
    public static String encryptAES(String content, String password) throws Exception {

        // 判断Key是否为16位
        byte[] raw = password.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");//"算法/模式/补码方式"
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
        return new BASE64Encoder().encode(encrypted);//此处使用BASE64做转码功能，同时能起到2次加密的作用。

    }

    /**
     * 解密AES加密过的字符串

     */
    public static String decryptAES(String content, String password)throws Exception {
        // 判断Key是否正确
        byte[] raw = password.getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] encrypted1 = new BASE64Decoder().decodeBuffer(content);//先用base64解密
        try {
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original);
            return originalString;
        } catch (Exception e) {
            System.out.println(e.toString());
            return null;
        }
    }

    public static void main(String[] args) {
        System.out.println(DesUtil.encrypt("user01"));
        System.out.println(DesUtil.encrypt("User01@2020"));
    }
}
